package de.lot.action;

import de.lot.auth.PasswordManager;
import de.lot.model.LotUser;
import de.lot.model.Role;
import javax.persistence.EntityManager;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Identity;

/**
 * AuthenticationManager checks if a user is in the database and if the password
 * entered is correct.
 * 
 * @author Stefan Kohler <kohler.stefan@gmail.com>
 */
@Name("authenticationManager")
public class AuthenticationManager {

    @Logger
    private Log log;
    @In
    private EntityManager entityManager;
    @In
    private Identity identity;
    @In
    private PasswordManager passwordManager;
    @Out(required = false)
    LotUser currentUser;

    /**
     * Authenticates an user on login.
     *
     * @return <code>true</code> if the user is in the db and
     *         the password is correct
     *         <code>false</code> if the user is not in the db or
     *         the password is incorrect
     */
    @Transactional
    public boolean authenticate() {
        log.info("username: #0, password: #1", identity.getUsername(), identity.getPassword());
        try {
            LotUser lotUser = (LotUser) entityManager.createQuery(
                    "select lu from LotUser lu where lu.username = :username").setParameter("username", identity.getUsername()).getSingleResult();
            if (!validatePassword(identity.getPassword(), lotUser)) {
                log.error("Password incorrect");
                return false;
            }

            if (lotUser.getRole() != null) {
                identity.addRole(lotUser.getRole().getName());
            }
            return true;
        } catch (Exception e) {
            log.error("Error occured: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Validates if the entered password matches the password stored in the
     * database
     *
     * @see PasswordManager
     * @param password  The entered password
     * @param lu        The user according to username
     * @return <code>true</code> if the password is correct
     *         <code>false</code> if the password is incorrect
     *
     */
    public boolean validatePassword(String password, LotUser lu) {
        return passwordManager.hash(password).equals(lu.getPasswordHash());
    }
}
